<!--
    TodoList.vue - 待办事项列表主组件
    
    这是应用的核心组件，负责管理整个待办事项列表的状态和行为
    功能特性：
    1. 显示待办事项列表
    2. 添加新的待办事项
    3. 删除已有的待办事项
    4. 管理应用的主要状态
    
    组件架构：
    - 容器组件（Container Component）
    - 管理状态和业务逻辑
    - 协调子组件之间的通信
-->

<template>
  <!-- 组件根容器 -->
  <div>
    <!-- 
            输入框组件 - 用于添加新的待办事项
            v-model="newTodoText" - 双向数据绑定，绑定到组件的newTodoText数据
            placeholder="New todo" - 输入框占位符文本
            @keydown.enter="addTodo" - 监听回车键按下事件，触发addTodo方法
            .enter是事件修饰符，只有按下回车键时才触发
        -->
    <BaseInputText v-model="newTodoText" placeholder="New todo" @keydown.enter="addTodo" />

    <!-- 
            待办事项列表 - 条件渲染
            v-if="todos.length" - 只有当todos数组有内容时才显示列表
            使用ul元素保持语义化的HTML结构
        -->
    <ul v-if="todos.length">
      <!-- 
                循环渲染待办事项
                v-for="todo in todos" - 遍历todos数组
                :key="todo.id" - 为每个列表项提供唯一的key，优化Vue的虚拟DOM diff算法
                :todo="todo" - 将当前todo对象作为props传递给子组件
                @remove="removeTodo" - 监听子组件发出的remove事件，调用removeTodo方法
            -->
      <TodoListItem v-for="todo in todos" :key="todo.id" :todo="todo" @remove="removeTodo" />
    </ul>

    <!-- 
            空状态提示 - 条件渲染
            v-else - 当todos数组为空时显示此提示
            提供友好的用户体验，告知用户如何使用应用
        -->
    <p v-else>列表为空，请在上方输入框中添加新的待办事项。</p>
  </div>
</template>

<script>
/**
 * TodoList组件脚本部分
 *
 * 这是一个容器组件（Container Component），负责：
 * 1. 管理应用状态（todos数组、输入框文本）
 * 2. 处理业务逻辑（添加、删除待办事项）
 * 3. 协调子组件通信
 */

// 导入子组件
import BaseInputText from "./BaseInputText.vue";
import TodoListItem from "./TodoListItem.vue";

// 全局变量，用于生成唯一的todo ID
// 使用let声明，可以在组件方法中修改
// 在实际项目中，ID生成可能会使用UUID或时间戳等更复杂的方案
let nextTodoId = 1;

export default {
  // 组件名称
  name: "TodoList",

  // 注册子组件
  components: {
    BaseInputText, // 基础输入框组件
    TodoListItem, // 待办事项单项组件
  },

  /**
   * 组件数据
   *
   * data必须是一个函数，返回数据对象
   * 这样确保每个组件实例都有独立的数据副本
   */
  data() {
    return {
      // 新待办事项的输入文本
      // 与BaseInputText组件通过v-model双向绑定
      newTodoText: "",

      // 待办事项数组 - 应用的核心数据
      // 每个todo对象包含id和text属性
      todos: [
        // 预设的示例数据，帮助用户理解应用功能
        {
          id: nextTodoId++, // 使用后递增运算符生成唯一ID
          text: "学习Vue.js",
        },
        {
          id: nextTodoId++,
          text: "学习单文件组件",
        },
        {
          id: nextTodoId++,
          text: "爱上前端开发",
        },
      ],
    };
  },

  /**
   * 组件方法
   *
   * 包含组件的所有业务逻辑方法
   */
  methods: {
    /**
     * 添加新的待办事项
     *
     * 触发时机：
     * 1. 用户在输入框中按下回车键
     * 2. 可以扩展为点击添加按钮等其他触发方式
     */
    addTodo() {
      // 去除输入文本的首尾空白字符
      // trim()方法可以防止用户输入纯空格的无效数据
      const trimmedText = this.newTodoText.trim();

      // 验证输入内容不为空
      if (trimmedText) {
        // 向todos数组添加新的待办事项对象
        this.todos.push({
          id: nextTodoId++, // 生成唯一ID
          text: trimmedText, // 使用处理后的文本
        });

        // 清空输入框，为下次输入做准备
        // 这里直接修改newTodoText，会通过v-model自动更新输入框
        this.newTodoText = "";
      }

      // 如果输入为空，不执行任何操作
      // 这样可以防止添加空的待办事项
    },

    /**
     * 删除指定的待办事项
     *
     * @param {number} idToRemove - 要删除的待办事项的ID
     *
     * 触发时机：
     * 用户点击TodoListItem组件中的删除按钮时，
     * 子组件会通过$emit('remove', todo.id)触发此方法
     */
    removeTodo(idToRemove) {
      // 使用filter方法创建新数组，排除指定ID的待办事项
      // filter会返回一个新数组，包含所有满足条件的元素
      this.todos = this.todos.filter((todo) => {
        // 返回true的元素会被保留，返回false的元素会被过滤掉
        return todo.id !== idToRemove;
      });

      // Vue的响应式系统会自动检测到todos数组的变化
      // 并更新相关的DOM元素（重新渲染TodoListItem组件）
    },
  },

  // 可以添加的其他选项：
  //
  // computed: {
  //   // 计算属性示例：统计待办事项数量
  //   todoCount() {
  //     return this.todos.length;
  //   },
  //
  //   // 计算属性示例：过滤已完成的待办事项（如果有完成状态）
  //   completedTodos() {
  //     return this.todos.filter(todo => todo.completed);
  //   }
  // },
  //
  // watch: {
  //   // 监听器示例：监听todos数组变化，可用于数据持久化
  //   todos: {
  //     handler(newTodos) {
  //       // 将数据保存到localStorage
  //       localStorage.setItem('todos', JSON.stringify(newTodos));
  //     },
  //     deep: true // 深度监听数组内部变化
  //   }
  // },
  //
  // created() {
  //   // 生命周期钩子示例：组件创建时从localStorage加载数据
  //   const savedTodos = localStorage.getItem('todos');
  //   if (savedTodos) {
  //     this.todos = JSON.parse(savedTodos);
  //   }
  // }
};
</script>

<!-- 
  注意：这个组件没有定义样式部分
  样式在父组件App.vue中定义，或者可以在这里添加组件特定的样式
  
  可以添加的样式示例：
  <style lang="scss" scoped>
  ul {
    list-style: none;
    padding: 0;
    margin: 16px 0;
  }
  
  p {
    text-align: center;
    color: #666;
    font-style: italic;
    margin: 32px 0;
  }
  </style>
-->
